package com.jingdianjichi.auth.domain.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.gson.Gson;
import com.jingdianjichi.auth.common.enums.IsDeleteFlagEnum;
import com.jingdianjichi.auth.common.enums.IsOpenFlagEnum;
import com.jingdianjichi.auth.domain.constant.AuthConstant;
import com.jingdianjichi.auth.domain.convert.AuthUserConvert;
import com.jingdianjichi.auth.domain.entity.AuthUserBO;
import com.jingdianjichi.auth.domain.redis.RedisUtil;
import com.jingdianjichi.auth.domain.service.AuthUserDomainService;
import com.jingdianjichi.auth.infra.basic.entity.*;
import com.jingdianjichi.auth.infra.basic.service.*;
import com.jingdianjichi.auth.infra.basic.service.impl.AuthPermissionServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户表(AuthUser)表服务实现类
 *
 * @author makejava
 * @since 2025-02-20 19:34:42
 */
@Service
public class AuthUserDomainServiceImpl implements AuthUserDomainService {
    @Resource
    private AuthUserService authUserService;
    @Resource
    private AuthUserRoleService authUserRoleService;
    @Resource
    private AuthRoleService authRoleService;
    @Resource
    private AuthRolePermissionService authRolePermissionService;

    @Resource
    private RedisUtil  redisUtil;

    private String authPermissionPrefix="auth.permission";

    private String authRolePrefix="auth.role";

    private String saltKey="jichi";

    private static  final  String LOGIN_PREFIX="loginCode";
    @Autowired
    private AuthPermissionServiceImpl authPermissionService;


    /**
     * 新增数据
     *
     * @param authUserBO 实例对象
     * @return 实例对象
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean register(AuthUserBO authUserBO) {
        //校验用户是否存在 username就是openid
        AuthUser existAuthuser=new AuthUser();
        existAuthuser.setUserName(authUserBO.getUserName());
        Integer existCount=authUserService.queryByCondition(existAuthuser);
        if(existCount>0){
            //库里有这个人
            return true;
        }
        AuthUser authUser= AuthUserConvert.INSTANCE.AuthUserConvertBoToAuthUser(authUserBO);
        authUser.setStatus(IsOpenFlagEnum.OPEN.getCode());
        authUser.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        if(!StringUtils.isBlank(authUser.getPassword())){
            authUser.setPassword(SaSecureUtil.md5BySalt(authUserBO.getPassword(),saltKey));
        }
        //建立一个初步角色用户关联
        AuthRole authRole=new AuthRole();
        authRole.setRoleKey(AuthConstant.NORMAL_USER);
        AuthRole roleResult = authRoleService.queryByCondition(authRole);
        Long RoleId = roleResult.getId();//获取角色id
        int count=authUserService.register(authUser); //插入后主键自动生成
        Long userId=authUser.getId();//获取用户Id
        AuthUserRole authUserRole=new AuthUserRole();
        authUserRole.setUserId(userId);
        authUserRole.setRoleId(RoleId);
        authUserRole.setIsDeleted(IsDeleteFlagEnum.UN_DELETED.getCode());
        authUserRoleService.insert(authUserRole);
        //redis角色缓存
        //用户：角色
        String roleKey= redisUtil.buildKey(authRolePrefix, authUser.getUserName());
        List<AuthRole>  roleList=new LinkedList<>();
        roleList.add(authRole);
        redisUtil.set(roleKey,new Gson().toJson(roleList));
        //根据角色id查出对应所有权限id
        AuthRolePermission authRolePermission=new AuthRolePermission();
        authRolePermission.setRoleId(RoleId);
        List<AuthRolePermission> authRolePermissionList=authRolePermissionService.
                queryByCondition(authRolePermission);
        List<Long> permissionIdList = authRolePermissionList.stream().map(AuthRolePermission::getPermissionId).collect(Collectors.toList());
        //根据权限id查出所有权限实体
        List<AuthPermission> authPermissionList= authPermissionService.queryByPermissionList(permissionIdList);
        //置入redis
        String permissionKey= redisUtil.buildKey(authPermissionPrefix, authUser.getUserName());
        redisUtil.set(permissionKey,new Gson().toJson(authPermissionList));
        return count>0;
    }

    /**
     * 修改数据
     *
     * @param authUser 实例对象
     * @return 实例对象
     */
    @Override
    public Boolean update(AuthUserBO authUserBO) {
        AuthUser authUser = AuthUserConvert.INSTANCE.AuthUserConvertBoToAuthUser(authUserBO);
        int count=authUserService.update(authUser);
        //对redis进行交互
        return  count>0;
    }



    @Override
    public SaTokenInfo doLogin(String validCode) {
        String buildKey=redisUtil.buildKey(LOGIN_PREFIX,validCode);
        String openId= redisUtil.get(buildKey);

        if(StringUtils.isBlank(openId)){
            return null;
        }
        AuthUserBO authUserBO=new AuthUserBO();
        authUserBO.setUserName(openId);
        this.register(authUserBO);
        //satoken 登录产生tokne验证
        StpUtil.login(openId);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        return tokenInfo;
    }

    @Override
    public AuthUserBO getUserInfo(AuthUserBO authUserBO) {
        AuthUser authUser=new AuthUser();
        authUser.setUserName(authUserBO.getUserName());
        AuthUser authUserInfo = authUserService.getUserInfo(authUser);
        AuthUserBO authUserInfoBo=AuthUserConvert.INSTANCE.authUserConvertEntityToAuthUserBO(authUserInfo);
        return authUserInfoBo;


    }
    @Override
    public List<AuthUserBO> listUserInfoByIds(List<String> ids) {
        return null;
    }

    /**
     * 删除用户信息
     *
     * @param authUserBO
     * @return
     */
    @Override
    public Boolean delete(AuthUserBO authUserBO) {
        AuthUser authUser =new AuthUser();
        authUser.setId(authUserBO.getId());
        authUser.setStatus(IsOpenFlagEnum.CLOSE.getCode());
        authUser.setIsDeleted(IsDeleteFlagEnum.DELETED.getCode());
        //逻辑删除
        int count=authUserService.update(authUser);
        //redis
        return  count>0;
    }

    /**
     * 启用禁用
     * @param authUserBO
     * @return
     */
    @Override
    public Boolean changeStatus(AuthUserBO authUserBO) {
        AuthUser authUser=new AuthUser();
        authUser.setId(authUserBO.getId());
        authUser.setStatus(authUserBO.getStatus());
        int count =authUserService.update(authUser);
        return  count>0;
    }

}
